package com.ctshk.rpc.order.goods.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.IsDeletedCode;
import com.ctshk.common.enums.SystemError;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.rpc.order.goods.dto.*;
import com.ctshk.rpc.order.goods.dto.resp.CommodityCostResp;
import com.ctshk.rpc.order.goods.entity.CommodityCost;
import com.ctshk.rpc.order.goods.entity.CommodityCostAttribute;
import com.ctshk.rpc.order.goods.entity.ShoppingSpecial;
import com.ctshk.rpc.order.goods.entity.ShoppingSpecialCommodity;
import com.ctshk.rpc.order.goods.mapper.*;
import com.ctshk.rpc.order.goods.req.ShoppingSpecialImportReq;
import com.ctshk.rpc.order.goods.req.ShoppingSpecialPageReq;
import com.ctshk.rpc.order.goods.service.IShoppingSpecialService;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * C端专题服务实现
 *
 * @author 黄利斌
 * @date 2021/5/28 11:11 上午
 */
@DubboService
public class ShoppingSpecialServiceImpl extends ServiceImpl<ShoppingSpecialMapper, ShoppingSpecial> implements IShoppingSpecialService {

    @Autowired
    private ShoppingSpecialMapper shoppingSpecialMapper;

    @Autowired
    private ShoppingSpecialCommodityMapper shoppingSpecialCommodityMapper;

    @Autowired
    private CommodityMapper commodityMapper;

    @Autowired
    private CommodityLabelMapper labelMapper;

    @Autowired
    private CommodityFileMapper fileMapper;

    @Autowired
    private CommodityKeyWordMapper keyWordMapper;

    @Autowired
    private CommodityRecommendMapper recommendMapper;

    @Autowired
    private CommodityCostMapper costMapper;

    @Autowired
    private CommodityCostAttributeMapper costAttributeMapper;

    @Override
    public ShoppingSpecialDetailedDTO findShoppingSpecialDetailed(ShoppingSpecialPageReq req) {
        // 参数校验
        if (req == null || null == req.getId()) {
            throw new BusinessException(SystemError.SYS_402);
        }
        // ID查询数据库对应的专题
        ShoppingSpecial shoppingSpecial = shoppingSpecialMapper.selectShoppingById(req.getId());
        if (shoppingSpecial == null) {
            throw new BusinessException(SystemError.MALL_MERCHANDISE_23032);
        }
        ShoppingSpecialDetailedDTO shoppingSpecialDetailedDTO = new ShoppingSpecialDetailedDTO();
        if (null != shoppingSpecial.getAppSpecialPictureUrl()) {
            List<ShoppingSpecialPageUrlDTO> list = JSON.parseArray(shoppingSpecial.getAppSpecialPictureUrl(), ShoppingSpecialPageUrlDTO.class);
            shoppingSpecialDetailedDTO.setAppSpecialPictureUrl(list.get(0).getUrl());
        }
        // 返回封装的专题DTO对象

//        if (hasKey(RedisConstants.GOODS_HOME_SPECIAL)) {
//            // 查询缓存专题数据
//            List<ShoppingSpecialDetailedDTO> specialDetailedDTO = JSON.parseObject(redisTemplate.opsForValue().get(RedisConstants.GOODS_HOME_SPECIAL), new TypeReference<List<ShoppingSpecialDetailedDTO>>() {
//            });
//            // 存储专题商品数据
//            for (ShoppingSpecialDetailedDTO detailedDTO : specialDetailedDTO) {
//                if (detailedDTO.getId().longValue() == shoppingSpecial.getId()) {
//                    shoppingSpecialDetailedDTO = EntityUtil.copy(detailedDTO, ShoppingSpecialDetailedDTO.class);
//                    if (CollectionUtils.isNotEmpty(detailedDTO.getCommodityDetailedList())) {
//                        List<ShoppingSpecialCommodityDetailedDTO> commodityDetailedDTO = EntityUtil.copyList(detailedDTO.getCommodityDetailedList(), ShoppingSpecialCommodityDetailedDTO.class);
//                        shoppingSpecialDetailedDTO.setCommodityDetailedList(commodityDetailedDTO);
//                    }
//                }
//            }
//            return shoppingSpecialDetailedDTO;
//        }

        // 缓存无数据查询数据库信息
        // 查询专题商品信息
//        QueryWrapper<ShoppingSpecialCommodity> shoppingSpecialCommodityQueryWrapper = new QueryWrapper<>();
//        shoppingSpecialCommodityQueryWrapper.lambda().eq(ShoppingSpecialCommodity::getSpecialId, shoppingSpecial.getId());
//        shoppingSpecialCommodityQueryWrapper.lambda().eq(ShoppingSpecialCommodity::getIsDeleted, 0);
        List<ShoppingSpecialCommodity> shoppingSpecialCommodityList = shoppingSpecialCommodityMapper.selectListById(shoppingSpecial.getId());
        List<ShoppingSpecialCommodityDetailedDTO> shoppingSpecialCommodityDetailedDTOS = EntityUtil.copyList(shoppingSpecialCommodityList, ShoppingSpecialCommodityDetailedDTO.class);
        // 遍历DTO对象
        if (CollectionUtils.isNotEmpty(shoppingSpecialCommodityDetailedDTOS)) {
            List<Long> ids = shoppingSpecialCommodityDetailedDTOS.stream().map(obj -> obj.getCommodityId()).collect(Collectors.toList());
            ids = ids.stream().distinct().collect(Collectors.toList()); //去重
            String commodityIds = ids.toString().substring(1, ids.toString().length() - 1);
            // 获取指定的商品信息
            List<com.ctshk.rpc.order.goods.dto.ShoppingSpecialCommodityDTO> commodityDTOS = commodityMapper.findAppShoppingSpecialCommodityByIds(commodityIds);
            for (com.ctshk.rpc.order.goods.dto.ShoppingSpecialCommodityDTO dto : commodityDTOS) {
                if (dto.getSpecificationsType().longValue() == 1) { // 单规格
                    CommodityCost cost = costMapper.findCommodityCostByCommodityId(dto.getId());
                    com.ctshk.rpc.order.goods.dto.resp.CommodityCostResp commodityCostResp = EntityUtil.copy(cost, com.ctshk.rpc.order.goods.dto.resp.CommodityCostResp.class);
                    if (CollectionUtils.isNotEmpty(dto.getCommodityCostResps())) {
                        List<com.ctshk.rpc.order.goods.dto.resp.CommodityCostResp> commodityCostResps = dto.getCommodityCostResps();
                        commodityCostResps.add(commodityCostResp);
                        dto.setCommodityCostResps(commodityCostResps);
                    } else {
                        List<CommodityCostResp> costResps = new ArrayList<>();
                        costResps.add(commodityCostResp);
                        dto.setCommodityCostResps(costResps);
                    }
                } else if (dto.getSpecificationsType().longValue() == 2) { //多规格
                    List<CommodityCostAttribute> commodityIdAndAttributeId = costAttributeMapper.findCostAttributeByCommodityIdAndAttributeId(dto.getId(), dto.getAttributeId());
                    List<CommodityCostAttributeDTO> commodityCostAttributeDTOS = EntityUtil.copyList(commodityIdAndAttributeId, CommodityCostAttributeDTO.class);
                    dto.setCommodityCostAttributeDTOS(commodityCostAttributeDTOS);
                }
            }

            // 对象集合转换成map
            Map<Long, com.ctshk.rpc.order.goods.dto.ShoppingSpecialCommodityDTO> commodityMap = commodityDTOS.stream().
                    collect(Collectors.toMap(com.ctshk.rpc.order.goods.dto.ShoppingSpecialCommodityDTO::getId, Function.identity(), (key1, key2) -> key1));
            // 商品图片、价格、名称等赋值到商品专题，用于前端页面展示
            List<ShoppingSpecialCommodityDetailedDTO> specialCommodityDetailedDTOS = new ArrayList<>();
            for (ShoppingSpecialCommodityDetailedDTO target : shoppingSpecialCommodityDetailedDTOS) {
                ShoppingSpecialCommodityDTO source = commodityMap.get(target.getCommodityId());
                if (null != source) {
                    target.setCommodityName(source.getCommodityName());
                    target.setFileUrl(source.getFileUrl());
                    target.setPrice(source.getCostPrice());
                    target.setStock(source.getStock());
                    target.setSpecificationsType(source.getSpecificationsType());
                    target.setCommodityCostResps(source.getCommodityCostResps());
                    target.setCommodityCostAttributeDTOS(source.getCommodityCostAttributeDTOS());
                }
                specialCommodityDetailedDTOS.add(target);
            }
            shoppingSpecialDetailedDTO.setCommodityDetailedList(specialCommodityDetailedDTOS);
        }
        return shoppingSpecialDetailedDTO;
    }

    @Override
    public Result<PageResponse<CommoditySpecialDTO>> importCommodity(ShoppingSpecialImportReq req) {
//        List<CommodityInfoListDTO> commodityAllList = findCommodityAllList(req.getKeyword(),null);
        List<CommoditySpecialDTO> commodityAllList = commodityMapper.findCommodityAllListBykeyword(req.getKeyword());
        Page<CommoditySpecialDTO> iPage = new Page<>(req.getPageNo(), req.getPageSize());
        PageResponse<CommoditySpecialDTO> result = new PageResponse<>(commodityAllList, iPage.getCurrent() == 1, commodityAllList.size() <= (iPage.getCurrent() * iPage.getSize()), commodityAllList.size(), iPage.getCurrent(), iPage.getSize());
        return Result.success(result);
    }

    /**
     * 获取到所有的商品成本后，根据商品属性分组
     *
     * @param singles 单规格商品集合
     * @return 商品属性分组后的商品集合
     */
    private Map<Long, List<CommodityCostDTO>> getSingleCommodityCostMapByAttributeId(List<CommodityInfoListDTO> singles) {
        Map<Long, List<CommodityCostDTO>> result = null;
        List<Long> singleCommodityIds = singles.stream().map(p -> p.getId()).collect(Collectors.toList());
        List<CommodityCost> list = costMapper.selectListByIds(singleCommodityIds, IsDeletedCode.NO.getCode());
        List<CommodityCostDTO> resultList = EntityUtil.copyList(
                list, CommodityCostDTO.class);
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(resultList)) {
            result = resultList.stream().collect(Collectors.groupingBy(obj -> obj.getCommodityAttributeId()));
        }
        return result;
    }

    /**
     * 获取到所有的商品成本属性后，根据属性分组
     *
     * @param multiples 多规格商品集合
     * @return 商品属性集合
     */
    private Map<Long, List<CommodityCostAttributeDTO>> getMultipleCommodityCostAttributeMapByAttributeId(List<CommodityInfoListDTO> multiples) {
        Map<Long, List<CommodityCostAttributeDTO>> result = null;
        List<Long> multipleCommodityIds = multiples.stream().map(p -> p.getId()).collect(Collectors.toList());
        List<CommodityCostAttribute> list = costAttributeMapper.selectByIds(multipleCommodityIds, IsDeletedCode.NO.getCode());
        List<CommodityCostAttributeDTO> costAttributeList = EntityUtil.copyList(list, CommodityCostAttributeDTO.class);
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(costAttributeList)) {
            result = costAttributeList.stream().collect(Collectors.groupingBy(obj -> obj.getCommodityAttributeId()));
        }
        return result;
    }

    /**
     * 查询商品数据封装
     *
     * @param lastNow
     * @return
     */
    public List<CommodityInfoListDTO> findCommodityAllList(String keyword, LocalDateTime lastNow) {
        // 过滤商品主表数据，根据主表数据去组装其他数据参数
        List<CommodityInfoListDTO> commodityList = commodityMapper.findCommodityInfoListByKeyWord(keyword, lastNow);
        if (org.springframework.util.CollectionUtils.isEmpty(commodityList)) {
            return null;
        }
        Map<Long, List<CommodityLabelDTO>> labelMap = null;
        Map<Long, List<CommodityFileDTO>> fileMap = null;
        Map<Long, List<CommodityKeyWordDTO>> keyWordMap = null;
        Map<Long, List<CommodityRecommendDTO>> recommendMap = null;

        List<Long> commodityIds = commodityList.stream().map(p -> p.getId()).collect(Collectors.toList());

        // 获取商品标签，并根据商品ID进行分组，用于后续的组装参数取值
        List<CommodityLabelDTO> labelList = labelMapper.findHtmlFiveCommodityLabelByCommodityIds(commodityIds);
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(labelList)) {
            labelMap = labelList.stream().collect(Collectors.groupingBy(obj -> obj.getCommodityId()));
        }

        // 获取商品文件，并根据商品ID进行分组，用于后续的组装参数取值
        List<CommodityFileDTO> fileList = fileMapper.findHtmlFiveCommodityFileByCommodityIds(commodityIds);
        if (CollectionUtils.isNotEmpty(fileList)) {
            fileMap = fileList.stream().collect(Collectors.groupingBy(obj -> obj.getCommodityId()));
        }

        // 获取商品关键词，并根据商品ID进行分组，用于后续的组装参数取值
        List<CommodityKeyWordDTO> keyWordList = keyWordMapper.findHtmlFiveCommodityKeyWordByCommodityIds(commodityIds);
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(keyWordList)) {
            keyWordMap = keyWordList.stream().collect(Collectors.groupingBy(obj -> obj.getCommodityId()));
        }

        // 获取商品推荐，并根据商品ID进行分组，用于后续的组装参数取值
        List<CommodityRecommendDTO> recommendList = recommendMapper.findHtmlFiveCommodityRecommendByCommodityIds(commodityIds);
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(recommendList)) {
            recommendMap = recommendList.stream().collect(Collectors.groupingBy(obj -> obj.getCommodityId()));
        }

        // 商品其他属性 一对一 查询赋值
        for (CommodityInfoListDTO commodityAllList : commodityList) {
            Long commodityId = commodityAllList.getId();
            commodityAllList.setId(commodityId);
            commodityAllList.setCommodityLabels(null == labelMap ? null : labelMap.get(commodityId));
            commodityAllList.setCommodityFiles(null == fileMap ? null : fileMap.get(commodityId));
            commodityAllList.setCommodityKeyWords(null == keyWordMap ? null : keyWordMap.get(commodityId));
            commodityAllList.setCommodityRecommends(null == recommendMap ? null : recommendMap.get(commodityId));
        }

        // 区分 单/多规格类型数据，因为组装的参数涉及表关联关系不一样
        Map<Integer, List<CommodityInfoListDTO>> specificationsTypeMap = commodityList.stream().collect(Collectors.groupingBy(obj -> obj.getCommodityAttribute().getSpecificationsType()));
        List<CommodityInfoListDTO> singles = specificationsTypeMap.get(1);
        List<CommodityInfoListDTO> multiples = specificationsTypeMap.get(2);

        // 单规格参数组装
        if (CollectionUtils.isNotEmpty(singles)) {
            Map<Long, List<CommodityCostDTO>> costs = getSingleCommodityCostMapByAttributeId(singles);
            for (CommodityInfoListDTO singlesCommodityAllList : singles) {
                Long commodityAttributeId = singlesCommodityAllList.getCommodityAttribute().getId();
                List<CommodityCostDTO> temps = costs.get(commodityAttributeId);
                if (org.apache.commons.collections.CollectionUtils.isNotEmpty(temps)) {
                    singlesCommodityAllList.setCommodityCosts(temps);
                }
            }
        }

        // 多规格参数组装
        if (CollectionUtils.isNotEmpty(multiples)) {
            Map<Long, List<CommodityCostAttributeDTO>> costAttributes = getMultipleCommodityCostAttributeMapByAttributeId(multiples);
            for (CommodityInfoListDTO multipleCommodityAllList : multiples) {
                Long commodityAttributeId = multipleCommodityAllList.getCommodityAttribute().getId();
                List<CommodityCostAttributeDTO> temps = costAttributes.get(commodityAttributeId);
                if (org.apache.commons.collections.CollectionUtils.isNotEmpty(temps)) {
                    multipleCommodityAllList.setCommodityCostAttributes(temps); // 讲商品成本属性设置到对应的商品对象
                    // 获取商品成本属相对应的商品成本
                    List<Long> costAttributeIds = temps.stream().map(p -> p.getId()).collect(Collectors.toList());
                    List<CommodityCost> commodityCostList = costMapper.selectByCommodityIdAndAttrId(multipleCommodityAllList.getCommodityAttribute().getCommodityId(), commodityAttributeId, costAttributeIds, IsDeletedCode.NO.getCode());
                    List<CommodityCostDTO> resultCostList = EntityUtil.copyList(commodityCostList, CommodityCostDTO.class);
                    Map<Long, List<CommodityCostDTO>> costAttributeMap = resultCostList.stream().collect(Collectors.groupingBy(obj -> obj.getCostAttributeId()));

                    for (CommodityCostAttributeDTO costAttribute : multipleCommodityAllList.getCommodityCostAttributes()) {
                        Long costAttributeId = costAttribute.getId();
                        List<CommodityCostDTO> commodityCost = costAttributeMap.get(costAttributeId);
                        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(commodityCost)) {
                            costAttribute.setCommodityCost(commodityCost.get(0));
                        }
                    }
                }
            }
        }
        return commodityList;
    }

    /**
     * redis中是否存在key
     *
     * @param key
     * @return
     */
    private boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }

    @Autowired
    private RedisTemplate<String, String> redisTemplate; // redis操作类
}
